package com.parenting.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.parenting.entities.ParentingShopAutDO;
import com.parenting.entities.ParentingShopDO;
import com.parenting.enums.ResultEnum;
import com.parenting.exception.BaseException;
import com.parenting.feign.controller.IFeignSystemPlatformUserController;
import com.parenting.feign.controller.IFeignSystemUserController;
import com.parenting.feign.entities.ShopAndUserFeignDTO;
import com.parenting.mapper.ParentingShopMapper;
import com.parenting.model.IMPage;
import com.parenting.model.UserDTO;
import com.parenting.request.*;
import com.parenting.request.platform.AddPlatformShopRequest;
import com.parenting.request.platform.ExamineApprove;
import com.parenting.request.platform.ShopSearchConditionRequest;
import com.parenting.response.UnclaimedListResponse;
import com.parenting.response.platform.*;
import com.parenting.service.ParentingShopAutService;
import com.parenting.service.ParentingShopService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.parenting.util.GaoDeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 店铺主表 服务实现类
 * </p>
 *
 * @author 烟台业达-王世玺
 * @since 2021-08-18
 */
@Service
@Slf4j
public class ParentingShopServiceImpl extends ServiceImpl<ParentingShopMapper, ParentingShopDO> implements ParentingShopService {

    @Override
    public void saveShop(UserDTO userDTO,ShopSaveRequest shop) {
        log.info("=======saveShop========= {} " , shop);
        if (!chekShop(shop)){
            throw  new BaseException(ResultEnum.SHOP_REPEAT);
        }
        StringBuffer buffer= new StringBuffer();
        buffer.append(shop.getProvince());
        buffer.append(shop.getCity());
        buffer.append(shop.getArea());
        buffer.append(shop.getShopAdd());
        String latAndLogByName = GaoDeUtil.getLatAndLogByName(buffer.toString());
        if (StringUtils.isNotEmpty(latAndLogByName)){
            String[] split = latAndLogByName.split(",");
            shop.setLongitude(split[0]);
            shop.setLat(split[1]);
        }else{
            throw new RuntimeException("地址填写错误 无法解析");
        }
        shop.setUserId(userDTO.getId());
        shop.setUserName(userDTO.getFullName());
        ParentingShopDO parentingShopDO = BeanUtil.copyProperties(shop, ParentingShopDO.class);
        baseMapper.insert(parentingShopDO);
    }

    @Override
    public void savePlatformShop(AddPlatformShopRequest shop) {
        ParentingShopDO parentingShopDO = BeanUtil.copyProperties(shop, ParentingShopDO.class);
        StringBuffer buffer= new StringBuffer();
        buffer.append(parentingShopDO.getProvince());
        buffer.append(parentingShopDO.getCity());
        buffer.append(parentingShopDO.getArea());
        buffer.append(parentingShopDO.getShopAdd());
        String latAndLogByName = GaoDeUtil.getLatAndLogByName(buffer.toString());
        if (StringUtils.isNotEmpty(latAndLogByName)){
            String[] split = latAndLogByName.split(",");
            parentingShopDO.setLongitude(split[0]);
            parentingShopDO.setLat(split[1]);
        }else{
            throw new RuntimeException("地址填写错误 无法解析");
        }
        baseMapper.insert(parentingShopDO);
    }

    @Override
    public void updateShop(ShopUpdateRequest shop) {

    }

    @Override
    public IMPage<UnclaimedListResponse> ListOfUnclaimedShops(UnclaimedListConditionRequest ucd) {
            IPage<UnclaimedListResponse> iPage = baseMapper.ListOfUnclaimedShops(ucd.getPage(), ucd);
            IMPage<UnclaimedListResponse> unclaimedListResponseIMPage = new IMPage<>();
            unclaimedListResponseIMPage.setCurrent(iPage.getCurrent());
            unclaimedListResponseIMPage.setSize(iPage.getSize());
            unclaimedListResponseIMPage.setRecords(iPage.getRecords());
            unclaimedListResponseIMPage.setTotal(iPage.getTotal());
        return unclaimedListResponseIMPage;
    }

    @Autowired
    private ParentingShopAutService parentingShopAutService;

    @Autowired
    private IFeignSystemUserController iFeignSystemUserController;

    @Autowired
    private RedissonClient redissonClient;

    @Transactional
    @Override
    public synchronized void ClaimShop(UserDTO userDTO, ShopAutRequest request) {

        log.info("======request=========== {}",request.getShopId());
        String lockKey = "lock:shopAndUser:"+request.getShopId();
        RLock rLock = redissonClient.getLock(lockKey);
        rLock.lock(5, TimeUnit.SECONDS);
        try {
            //校验是否已经认领过店铺
            if(!iFeignSystemUserController.ChekShopClaim(request.getShopId())){
                throw  new BaseException(-1,"该店铺已被其他（她）人员认领！");
            }
            if(iFeignSystemUserController.ChekShopClaimUser(userDTO.getId())){
                throw  new BaseException(-1,"当前用户领取过店铺！");
            }
            //根据 店铺ID 查询 店铺信息
            ParentingShopDO parentingShopDO = baseMapper.selectById(request.getShopId());
            parentingShopDO.setUserId(userDTO.getId());
            parentingShopDO.setUserName(userDTO.getFullName());
            parentingShopDO.setState(3);
            parentingShopDO.setApplyDate(new Date());
            //修改店铺信息
            baseMapper.updateById(parentingShopDO);
            //保存店铺资质
            ParentingShopAutDO parentingShopAutDO = BeanUtil.copyProperties(request, ParentingShopAutDO.class);
            parentingShopAutService.save(parentingShopAutDO);
            //封装店铺与用户的关系
            ShopAndUserFeignDTO su=new ShopAndUserFeignDTO();
            su.setShopId(parentingShopDO.getId());
            su.setUserId(userDTO.getId());
            iFeignSystemUserController.shopAndUser(su);
        }finally {
            rLock.unlock();
            log.info("解锁成功");
        }

    }

    @Override
    public boolean chekShop(ChekShopRequest shop) {
        LambdaQueryWrapper<ParentingShopDO> wrapper =new LambdaQueryWrapper();
        wrapper.eq(ParentingShopDO::getProvince,shop.getProvince());
        wrapper.eq(ParentingShopDO::getCity,shop.getCity());
        wrapper.eq(ParentingShopDO::getArea,shop.getArea());
        wrapper.eq(ParentingShopDO::getShopName,shop.getShopName());
        wrapper.eq(ParentingShopDO::getShopAdd,shop.getShopAdd());
        return !(baseMapper.selectCount(wrapper)>0);
    }

    @Override
    public IMPage<PageShopListResponse> pageShopList(ShopSearchConditionRequest request) {
        LambdaQueryWrapper<ParentingShopDO> wrapper=new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(request.getShopName())){
            wrapper.like(ParentingShopDO::getShopName,request.getShopName());
        }
        if (StringUtils.isNotEmpty(request.getShopType())){
            wrapper.like(ParentingShopDO::getClassification,request.getShopType());
        }
        if (null!=request.getClaim()&&request.getClaim()==4){
            wrapper.eq(ParentingShopDO::getState,request.getClaim());
        }else  if (null!=request.getClaim()){
            wrapper.ne(ParentingShopDO::getState,4);
        }
        IPage<ParentingShopDO> parentingShopDOIPage = baseMapper.selectPage(request.getPage(), wrapper);
        IMPage<PageShopListResponse> page=new IMPage<>();
        page.setTotal(parentingShopDOIPage.getTotal());
        page.setCurrent(parentingShopDOIPage.getCurrent());
        page.setSize(parentingShopDOIPage.getSize());
        if (null!=parentingShopDOIPage.getRecords()&&parentingShopDOIPage.getSize()>0){
            List<PageShopListResponse> list=new ArrayList<>();
            for (ParentingShopDO shop:parentingShopDOIPage.getRecords()) {
                list.add( BeanUtil.copyProperties(shop, PageShopListResponse.class));
            }
            page.setRecords(list);
        }
        return page;
    }
 
    @Override
    public StoreDetailsResponse getShopById(String id) {
        StoreDetailsResponse storeDetailsResponse=new StoreDetailsResponse();
        ParentingShopDO parentingShopDO = baseMapper.selectById(id);
        if (null!=parentingShopDO){
            EssentialInformation essentialInformation = BeanUtil.copyProperties(parentingShopDO, EssentialInformation.class);
            essentialInformation.setRegion(parentingShopDO.getProvince()+parentingShopDO.getArea()+parentingShopDO.getCity());
            storeDetailsResponse.setEssentialInformation(essentialInformation);
        }
        if (parentingShopDO.getState()==4){
            ParentingShopAutDO one = parentingShopAutService.getOne(new LambdaQueryWrapper<ParentingShopAutDO>().eq(ParentingShopAutDO::getShopId, id));
            QualificationInformation qualificationInformation = BeanUtil.copyProperties(one, QualificationInformation.class);
            storeDetailsResponse.setQualificationInformation(qualificationInformation);
        }
        return storeDetailsResponse;
    }

    @Override
    @Transactional
    public void deleteShopById(String id) {
        ParentingShopDO parentingShopDO = baseMapper.selectById(id);
        Integer state = parentingShopDO.getState();
        if ((null!=state&&state==3)||state==4){
            throw new BaseException(ResultEnum.SHOP_NOT_DELETE);
        }
        parentingShopAutService.remove(new LambdaQueryWrapper<ParentingShopAutDO>().eq(ParentingShopAutDO::getShopId,id));
        baseMapper.deleteById(id);
    }

    @Override
    public List<ClaimNotice> getClaimNoticeList(Integer state) {

        return baseMapper.getClaimNoticeList(state);
    }
    @Autowired
    private IFeignSystemPlatformUserController iFeignSystemPlatformUserController;
    @Override
    public void updateExamineShop(ExamineApprove examineApprove) {
          LambdaUpdateWrapper<ParentingShopDO> wrapper=new LambdaUpdateWrapper();
          wrapper.set(ParentingShopDO::getState,examineApprove.getState());
          wrapper.eq(ParentingShopDO::getId,examineApprove.getShopId());
          this.update(wrapper);
          if (examineApprove.getState()==4){
              iFeignSystemPlatformUserController.permissionInitialization(examineApprove.getUserId());
          }
    }

    private boolean chekShop(ShopSaveRequest shop) {
        LambdaQueryWrapper<ParentingShopDO> wrapper =new LambdaQueryWrapper();
        wrapper.eq(ParentingShopDO::getProvince,shop.getProvince());
        wrapper.eq(ParentingShopDO::getCity,shop.getCity());
        wrapper.eq(ParentingShopDO::getArea,shop.getArea());
        wrapper.eq(ParentingShopDO::getShopName,shop.getShopName());
        wrapper.eq(ParentingShopDO::getShopAdd,shop.getShopAdd());
        return !(baseMapper.selectCount(wrapper)>0);
    }
}
